<template>
  <scroll-view
    class="LoadingScroller class"
    scroll-y
    :lower-threshold="100"
    scroll-with-animation
    @scrolltolower="scrolltolowerHandler"
  >
    <slot />
    <view class="footer" v-if="loading || showEndingText()">
      {{ loading ? '加载中...' : '- 我是有底线的 -' }}
    </view>
  </scroll-view>
</template>
<script lang="ts">
import Vue from '@/utils/Vue';
import { PropType } from 'vue';
import ITableResponse from '@/interfaces/ITableResponse';

interface IData {
  total: number;
  pageIndex: number;
  loading: boolean;
  dataSource: any[];
}

export default Vue.extend({
  data(): IData {
    return {
      pageIndex: this.startIndex,
      total: 0,
      loading: false,
      dataSource: [],
    };
  },
  options: {
    virtualHost: true,
  },
  externalClasses: ['class'],
  components: {},
  props: {
    pageSize: {
      type: Number,
      default: 10,
    },

    startIndex: {
      type: Number,
      default: 1,
    },

    /**
     * 请求一页数据的函数，(page, pageSize, params)=>Promise<{total}>
     */
    requestFunction: Function as PropType<
      (page: number, pageSize: number) => Promise<ITableResponse>
    >,
  },
  mounted() {
    this.requestData();
  },
  methods: {
    reset() {
      this.pageIndex = this.startIndex;
      this.total = 0;
      this.loading = false;
      this.dataSource = [];
      this.requestData();
    },
    scrolltolowerHandler() {
      this.triggerScroll();
    },

    triggerScroll() {
      if (this.loading) {
        return;
      }
      const maxIndex = this.getMaxIndex();
      if (this.pageIndex > maxIndex) {
        return;
      }
      if (this.total) {
        this.requestData();
      }
    },

    getMaxIndex() {
      const result = Math.ceil(this.total / this.pageSize);
      return result;
    },

    requestData() {
      this.loading = true;
      if (this.requestFunction) {
        return this.requestFunction(this.pageIndex, this.pageSize)
          .then((res) => {
            this.total = res.total;
            this.dataSource = this.dataSource.concat(res.dataSource);
            this.pageIndex++;
            this.$forceUpdate();
          })
          .finally(() => {
            this.loading = false;
          });
      }
    },

    showEndingText() {
      return !this.loading && this.pageIndex > this.getMaxIndex();
    },
  },
});
</script>
<style lang="less" scoped>
.LoadingScroller {
  height: 100%;
  box-sizing: border-box;
  overflow: auto;
  .footer {
    padding: 20px;
    text-align: center;
    color: #aaa;
    font-size: 14px;
  }
}
</style>
